package com.ushine.web.component.design.chain.handler;

import com.ushine.web.component.design.chain.config.ChainBaseParams;
import com.ushine.web.component.exception.ServiceException;
import com.ushine.web.component.http.HttpResponseVO;
import com.ushine.web.component.http.HttpStatus;
import lombok.extern.slf4j.Slf4j;

/**
 * @Author: yls
 * @Date: 2021/12/24 10:19
 * @Description: 父级链
 * @Version 1.0
 */
@Slf4j
public abstract class AbstractChainTemplateHandler<T extends ChainBaseParams> {


    /**
     * 下一个责任链
     */
    private AbstractChainTemplateHandler<T> chainTemplateHandler;

    /**
     * 优先级：执行顺序，值越小，优先级越高
     */
    private int order;


   /**
    * 功能描述:
    * 〈具体执行逻辑〉
    *
    * @param t 实体对象
    * @return : com.ushine.web.component.http.HttpResponseVO<?>
    * @author : yls
    * @date : 2022/3/11 15:57
    * @throws ServiceException 服务端自定义异常
    */
    protected abstract HttpResponseVO<?> process(T t) throws ServiceException;


    /**
     * 抽出一个模板：用于外部调用的入口
     */
    public HttpResponseVO<?> execute(T t) throws ServiceException {
        log.info("开始执行：{},{},{}", t.getName(), this.getClass(), t);
        HttpResponseVO<?> responseVO = process(t);
        log.info("结束执行：{},{},{}", t.getName(), this.getClass(), responseVO);
        if (responseVO.getCode() == HttpStatus.SC_OK) {
            return nextService(t, responseVO);
        }
        return responseVO;
    }


    /**
     * 将执行下一次操作的行为，改为我们的入口操作
     */
    private HttpResponseVO<?> nextService(T t, HttpResponseVO<?> httpResponseVO) throws ServiceException {
        if (chainTemplateHandler != null) {
            return chainTemplateHandler.execute(t);
        }
        return httpResponseVO;
    }

    public AbstractChainTemplateHandler<T> getAbstractChainTemplateHandler() {
        return chainTemplateHandler;
    }

    public void setAbstractChainTemplateHandler(AbstractChainTemplateHandler<T> abstractChainTemplateHandler) {
        this.chainTemplateHandler = abstractChainTemplateHandler;
    }

    public int getOrder() {
        return order;
    }

    public void setOrder(int order) {
        this.order = order;
    }

}
